import 'dart:convert'; // 导入库以便使用 jsonEncode
import 'package:cbec_app/components/http/api.dart';
import 'package:cbec_app/entity/base_entity.dart';
import 'package:cbec_app/routes/routes.dart';
import 'package:cbec_app/components/app_conifg.dart';
import 'package:cbec_app/utils/AppData.dart';
import 'package:cbec_app/utils/Tools.dart';
import 'package:cbec_app/utils/logger.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart' hide Response;

import '../../utils/EventMgr.dart';

/// 请求拦截白名单
const requestWhiteList = [Api.accountLogin];

///响应拦截白名单
const responseWhiteList = [Api.carGoodsNum, Api.carList];

/// 全局标志变量，防止重复触发登录过期逻辑
bool _hasRedirectedToLogin = false;

abstract class BaseNetwork {
  BaseNetwork._();
  // 超时时间 1min dio中是以毫秒计算的
  static const Duration timeout = Duration(seconds: 60);
  static Dio dio = getInstance();

  ///dio实例
  static Dio getInstance() {
    /// 全局属性：请求前缀、连接超时时间、响应超时时间
    var options = BaseOptions(connectTimeout: timeout, receiveTimeout: timeout, baseUrl: AppConfig.getBaseUrl, headers: {}
        // responseType: ResponseType.json,
        // validateStatus: (status) {
        //   // 不使用http状态码判断状态，使用AdapterInterceptor来处理（适用于标准REST风格）
        //   return true;
        // },
        );

    dio = Dio(options);

    // // 配置抓包
    // if (!kReleaseMode) {
    //   (dio?.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
    //       (HttpClient client) {
    //     client.idleTimeout = const Duration(seconds: 5);
    //     client.findProxy = (uri) {
    //       // proxyEd = true;
    //       return AppConfig.networkInterfaceDebugging;
    //     };
    //     // 代理工具会提供一个抓包的自签名证书，会通不过证书校验，所以我们禁用证书校验
    //     client.badCertificateCallback =
    //         (X509Certificate cert, String host, int port) => true;
    //     return null;
    //   };
    // }

    ///

    ///设置请求拦截器,设置响应拦截器 和 设置错误捕获
    dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        if (options.method == 'POST' || options.method == 'PUT') {
          options.headers = {
            'Content-Type': 'application/json',
          };
        } else if (options.method == 'GET' || options.method == 'DELETE') {
          options.headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
          };
        }
        final result = requestWhiteList.where((element) => options.path.contains(element));
        if (result.isEmpty) {
          //为不在白名单请求添加header
          if (AppData.tokenName != '') {
            logger.i('token : ${AppData.tokenValue}');
            options.headers[AppData.tokenName!] = AppData.tokenValue;
          } else {
            // logger.e('无token请求，将被拦截');
          }
        }
        return handler.next(options);
      },
      onResponse: (response, handler) {
        print('headers ===== ${response.requestOptions.headers}');
        print('path ===== ${response.requestOptions.path}');
        print('method ===== ${response.requestOptions.method}');
        print('response ===== ${response}');
        final result = responseWhiteList.where((element) => response.requestOptions.path.contains(element));
        if (result.isEmpty) {
          // 不在白名单
          BaseEntity entity = BaseEntity.fromJson(response.data);
          final code = entity.code;
          if (entity.code == 11011 || entity.code == 401) {
            Tools.hideLoading();
            _handleLoginExpired();
          } else if (code == 501) {
            Tools.hideLoading();
            showIOSDialog(entity.msg!);
          } else {
            return handler.next(response);
          }
        } else {
          // 在白名单
          return handler.next(response);
        }
      },
      onError: (error, handler) {
        logger.e('捕获错误 ${error.toString()}');
        Tools.showToast('请求错误：${error.message}', duration: const Duration(seconds: 3));

        return handler.next(error);
      },
    ));
    return dio;
  }

  ///get请求
  ///type 请求类型，将根据请求类型设置url及端口
  ///path 请求路径，复制文档路径即可
  ///params 请求参数
  static Future<Map<String, dynamic>> get<T>(
    ApiType type,
    String path, {
    Map<String, dynamic> params = const {},
  }) async {
    String url = Api.getApiPrefix(type) + path;
    logger.i("get请求地址1111：$url,参数$params");
    Response response = await dio.get(url, queryParameters: params);
    BaseEntity result = BaseEntity.fromJson(response.data);
    if (result.code == 200) {
      String prettyData = const JsonEncoder.withIndent('  ').convert(response.data); // 格式化 JSON 数据
      logger.d("请求成功，返回数据：\n$prettyData"); // 打印格式化后的数据
      // logger.d("请求成功，返回数据：\n${response.data}"); // 打印格式化后的数据
      return response.data;
    } else {
      logger.e('请求状态异常 ${result.toJson()}');
      Tools.hideLoading();
      if (result.code != 11011 && result.code != 401) {
        Tools.showToast(result.msg ?? '');
      }
      throw Exception(result.msg ?? '');
    }
  }

  ///post请求
  ///type 请求类型，将根据请求类型设置url及端口
  ///path 请求路径，复制文档路径即可
  ///params 请求参数
  static Future<Map<String, dynamic>> post<T>(ApiType type, String path, {Map<String, dynamic> params = const {}}) async {
    String url = Api.getApiPrefix(type) + path;
    logger.i("post请求地址：$url,参数$params");
    Response response = await dio.post(url, data: params);
    BaseEntity result = BaseEntity.fromJson(response.data);
    if (result.code == 200) {
      String prettyData = const JsonEncoder.withIndent('  ').convert(response.data); // 格式化 JSON 数据
      logger.i("请求成功，返回数据：\n$prettyData"); // 打印格式化后的数据
      return response.data;
    } else {
      logger.e('请求状态异常 ${result.toJson()}');
      Tools.hideLoading();
      if (result.code != 11011 && result.code != 401) {
        Tools.showToast(result.msg ?? '');
      }
      throw Exception(result.msg ?? '');
    }
  }

  ///delete请求
  static Future<Map<String, dynamic>> delete<T>(ApiType type, String path, {Map<String, dynamic> params = const {}}) async {
    String url = Api.getApiPrefix(type) + path;
    logger.i("delete请求地址：$url,参数$params");
    Response response = await dio.delete(url, data: params);
    BaseEntity result = BaseEntity.fromJson(response.data);
    if (result.code == 200) {
      return response.data;
    } else {
      logger.e('请求状态异常 ${result.toJson()}');
      Tools.hideLoading();
      if (result.code != 11011 && result.code != 401) {
        Tools.showToast(result.msg ?? '');
      }
      throw Exception(result.msg ?? '');
    }
  }

  ///put请求
  static Future<Map<String, dynamic>> put<T>(ApiType type, String path, {Map<String, dynamic> params = const {}}) async {
    String url = Api.getApiPrefix(type) + path;
    logger.i("put请求地址：$url,参数$params");
    Response response = await dio.put(url, data: params);
    BaseEntity result = BaseEntity.fromJson(response.data);

    if (result.code == 200) {
      return response.data;
    } else {
      logger.e('请求状态异常 ${result.toJson()}');
      Tools.hideLoading();
      if (result.code != 11011 && result.code != 401) {
        Tools.showToast(result.msg ?? '');
      }
      throw Exception(result.msg ?? '');
    }
  }

  /// 处理登录过期逻辑
  static void _handleLoginExpired() {
    if (_hasRedirectedToLogin) return;

    _hasRedirectedToLogin = true;

    // 清空登录信息
    AppData.sid = AppData.sid;
    AppData.uid = '';
    AppData.tokenName = '';
    AppData.tokenValue = '';
    AppData.avatar = "default_avatar.png";
    AppData.nickname = "请登录";
    AppData.phoneNumber = "";
    AppData.isLogin = false;
    Tools.showToast('登录过期，请登录');
    Get.toNamed(Routes.login);
    EventMgr.send(EventType.refreshLogin);
    EventMgr.send(EventType.refreshLogout);
    EventMgr.send(EventType.refreshCar);

    Tools.showToast('登录过期，请登录');
    Get.toNamed(Routes.login)?.then((_) {
      _hasRedirectedToLogin = false; // 重置标志位
    });
  }
}

/// 实名认证拦截弹窗
void showIOSDialog(String message) {
  showCupertinoDialog(
    context: Get.context!,
    builder: (context) {
      return CupertinoAlertDialog(
        title: Text('提示'), // 弹窗标题
        content: Text(message), // 弹窗内容
        actions: [
          CupertinoDialogAction(
            onPressed: () {
              Navigator.pop(context); // 关闭弹窗
            },
            child: Text('取消'),
          ),
          CupertinoDialogAction(
            onPressed: () {
              Navigator.pop(context); // 关闭弹窗
              Get.toNamed(Routes.userAuth); // 跳转到目标页面
            },
            isDefaultAction: true,
            child: Text('确定'),
          ),
        ],
      );
    },
  );
}
